export { }
// 类型推断

// 从赋值的类型中推断出来  类型从右向左推断
let foo = 1 // number
let bar = 'smd' // string

// 通过return 推断返回值的类型 (底部流出) 
function add(a: number, b: number) { // function add(a: number, b: number): number
  return a + b
}
// 从左向右
type Sum = (a: number, b: number) => number
let sum: Sum = (a, b) => { // function(a: number, b: number): number
  return a + b
}
let person = {
  name: 'string',
  age: 18
}
let { name, age } = person // name: string   age: number

// 接口
interface DefaultProps {
  name?: string
  age?: number
}
let defaultprops: DefaultProps = {
  name: 'smd',
  age: 18
}
let prop = {
  ...defaultprops,
  home: 'bj'
}
// 被接口定义过的变量  赋值给其他变量之后  该变量会继承其类型
type Props = typeof prop
/**
type Props = {
    home: string;
    name?: string | undefined;
    age?: number | undefined;
}
 */

// number + any = any
function addOne(a: any) {
  return a + 1
}
function sum3(a: number, b: number) {
  return a + addOne(b)
}
let s3 = sum3(1, 3) // let s3: any

// 交叉类型 &
interface Bird {
  name: string,
  fly(): void
}
interface Person {
  talk(): void
}
type BirdMan = Bird & Person
let p1: BirdMan = {
  name: 'xxx',
  fly() { },
  talk() { }
}

function mixin<T, U>(one: T, two: U) {
  let rest = <(T & U)>{} // 将rest定义为T和U的交集类型
  for (let key in one)
    (<T>rest)[key] = one[key] // 赋值时将rest断言成T类型

  for (let key in two)
    (<U>rest)[key] = two[key]// 赋值时将rest断言成U类型

  return rest
}
let x = mixin({ name: 'smd' }, { age: 18 })

// 索引访问操作符
interface Person5 {
  name: string
  age: number
  job: {
    name: string
  }
}
let p5: Person5['job'] = {
  name: 'qd'
}

// 映射类型
interface Person6 {
  name: string,
  age: number
}
type PartPerson = { // 将Person6中的属性变为可选的类型
  [key in keyof Person6]?: Person6[key]
}
type PPerson = Partial<Person6>// 使用内置类型Partial {name?: string | undefined; age?: number | undefined;}
// 内置类型Partial源码
type Partial<T> = { // Partial
  [key in keyof T]?: T[key]
}

